﻿/**
 * Tip.js
 */
$.Tip_Version = 20080122; 
$.Tip_DefaultSets = {
	delay: 0,
	zIndex: 1000,
	deltaX:15,
	deltaY: 10,
	timeToHide: 1,
	delayHide: true,
	effect: true
};
$.Tip = $({
	__init: function (e, sets) {
		this.e = $E(e);
		this.sets = $.extend(sets || {}, $.Tip_DefaultSets, true);
		if (this.sets.effect) {
			this.showEffect = $.effect({
				render: this.setOpacity.bind(this),
				duration:0.5,
				onStart: (function () { this.setOpacity(0); this.e.$('$show') }).bind(this)
			});
			this.hideEffect = $.effect({
				render: this._hide.bind(this),
				duration:0.3,
				onFinish: (function () { this.e.$('$hide') }).bind(this)
			});
			this.appearStep = 1 / this.sets.appearCounts;
		}
		this.e.css({position:'absolute', 'z-Index': this.sets.zIndex, display:'none'});
		if (!this.sets.es) {
			this.sets.es = [this.e];
		} else if ($.isString(this.sets.es)) {
			this.sets.es = [this.sets.es];
		}
		for (var i = 0; i < this.sets.es.length; i ++) {
			this.sets.es[i] = $E(this.sets.es[i]);	
		}
		if (this.sets.delayHide) {
			this.e.mouseover(this._mouseoverTip.bind(this));
			this.e.mouseout(this._mouseoutTip.bind(this));	
		}	
	},
	_hide: function (pos) {
		this.setOpacity( $.Effect.Transitions.reverse(pos));
	},
	_mouseoverTip: function() {
		if (this.hideTimer) {
			$.Timer.remove(this.hideTimer);
			this.hideTimer = null;	
		}	
		(this.sets.onmouseoverTip || $.empty) (this);
	},
	_mouseoutTip: function () {
		(this.sets.onmouseoutTip || $.empty) (this);
		this.hide();	
	},
	_setPosition: function (x, y, ey) {
		var bodySize = {width:document.body.clientWidth, height:document.body.clientHeight};
		var tipSize = this._tipSize();	
		var left = x, top = y, dx = this.sets.deltaX, dy = this.sets.deltaY + Math.round(ey/2), tw = tipSize.width, th = tipSize.height;
		var px =  window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
    		var py =  window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
		var pos;
		var cannotbe = [top -py - dy - th < 0 ? 't' : '', left - px + dx + tw > bodySize.width ? 'r' : '', 
				     top - py + dy + th > bodySize.height ? 'b' : '', left - px - dx - tw < 0 ? 'l' : ''];
		pos = cannotbe.include('t') ? 'b' : 't';
		pos += cannotbe.include('r') ? 'l' : 'r';
		switch (pos) {
			  case 'bl':
			    	left -= (tw + dx);
			    	top += dy;
			    	break;
			  case 'br':
			    	left += dx;
			    	top += dy;
			    	break;
			  case 'tl':
			    	left -= (tw + dx);
			    	top -= (th + dy);
			    	break;
			  case 'tr':
			  default:
			    	left += dx;
			    	top -= (th + dy); 	
		}
		this.e.css({left: left + 'px', top: top + 'px'});
	},
	_tipSize: function () {
		var ret = {};
		if (this.sets.width && this.sets.height) {
			ret.width = this.sets.width;
			ret.height = this.sets.height;	
		} else {
			if (this.e.css('display') == 'none') {
				this.e.$('$show');
				this.__temp = true;
			}
			ret.width = this.e.$('offsetWidth');
			ret.height = this.e.$('offsetHeight');
			if (this.__temp) {
				this.e.$('$hide');	
				this.__temp = false;
			}
		}
		return ret;	
	},
	content: function () {
		var cs = $.isArray(arguments[0]) ? arguments[0] : [].concat($A(arguments));
		for (var i = 0; i < cs.length; i ++) {
			if (!$.isString(cs[i])) continue;
			if (this.sets.es[i]) this.sets.es[i].html(cs[i]);	
		}	
	},
	hide: function () {
		this.__show = false;
		if (this.showTimer) {
			$.Timer.remove(this.showTimer);
			this.showTimer = null;
			return;
		}
		if (this.sets.delayHide && !this.hideTimer) {
			this.hideTimer = $.Timer.add({callback: this.hide.bind(this), timespan: this.sets.timeToHide});
			return;	
		}
		this.hideTimer = null;
		(this.sets.beforeHide || $.empty) (this);
		if (!this.sets.effect) return e.$('$hide');	
		$.Effect.add(this.hideEffect);
	},
	unfixedShow: function (event) {
		if (!this.__show) this.show(event, arguments[1]);
		x = $(event, 'x'), y = $(event, 'y'), ey = $(event, 'element').offsetHeight || 0;
		this._setPosition(x, y, ey);	
	},
	setOpacity: function (a) {
		this.e.css({opacity: a, filter: 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + Math.round(a * 100) + ')'});
	},
	show: function (event) {
		if (!event.timerCall && this.__show) return;
		this.__show = true;
		var x, y, ey;
		if (!event.timerCall) {
			x = $(event, 'x');
			y = $(event, 'y');
			ey = $(event, 'element').offsetHeight || 0;
		}
		if (this.hideTimer) {
			$.Timer.remove(this.hideTimer);
			this.hideTimer = null;
			this.e.$('$hide');	
		}
		if (this.sets.delay !== 0) {
			if (this.showTimer && !event.timerCall) {
				$.Timer.remove(this.showTimer);
				this.showTimer = null;
			}
			if (!this.showTimer) {
				this.showTimer = $.Timer.add({timespan: this.sets.delay, callback: this.show.bind(this, {timerCall: 1, x: x, y: y, ey: ey}, arguments[1])});
				return;	
			} 
			this.showTimer = null;
			x = event.x;
			y = event.y;
			ey = event.ey;	
		} 
		if (arguments[1]) this.content(arguments[1]);
		this._setPosition(x, y, ey);
		(this.sets.beforeShow || $.empty) (this);
		if (!this.sets.effect) 
		{
			this.e.$('$show');	
			return;
		}
		$.Effect.add(this.showEffect);
	}
});